﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using NHibernate.Cfg;
using System.Threading;

namespace NHibernate.DAL
{
    /// <summary>
    /// ISession抽象类
    /// </summary>
    public abstract class DataContext : IDisposable
    {
        static Dictionary<string, ISessionFactory> dicSessionFactory = new Dictionary<string, ISessionFactory>();
        ISessionFactory factory = null;
        private static Mutex m_mutex = new Mutex();

        public ISession Session
        {
            get;
            set;
        }

        private string hibernateConfig;

        public DataContext(string hibernateConfig)
        {
            this.hibernateConfig = hibernateConfig;
            dicSessionFactory.TryGetValue(hibernateConfig, out factory);
            if (factory == null)
            {
                factory = createSessionFactory();
            }
            Session = CreateSession();
        }

        ISessionFactory createSessionFactory()
        {
            if (factory == null)
            {
                m_mutex.WaitOne();
                try
                {
                    string path = System.AppDomain.CurrentDomain.BaseDirectory + "App_Data\\" + hibernateConfig;
                    string dir = System.AppDomain.CurrentDomain.BaseDirectory + "App_Data\\mapping\\" + hibernateConfig.Substring(0, hibernateConfig.IndexOf("."));
                    Configuration cfg = new Configuration().Configure(path).AddDirectory(new System.IO.DirectoryInfo(dir));
                    factory = cfg.BuildSessionFactory();
                    dicSessionFactory.Add(hibernateConfig, factory);
                    return factory;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    m_mutex.ReleaseMutex();
                }
            }
            else
            {
                return factory;
            }
        }

        ISession CreateSession()
        {
            return factory.OpenSession();
        }

        ISession CreateSession(IDbConnection con)
        {
            return factory.OpenSession(con);
        }

        public void Dispose()
        {
            try
            {
                Session.Close();
            }
            catch
            {
            }
        }
    }
}
